package com.gitee.wsl.android.ext

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.Intent.ShortcutIconResource
import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.database.Cursor
import android.graphics.drawable.Icon
import android.net.Uri
import android.os.Build
import androidx.annotation.AnyRes
import com.gitee.wsl.android.ext.ApplicationInit.application
import timber.log.Timber


/**
 * detail: 快捷方式工具类
 * @author Ttt
 * <pre>
 *     所需权限
 *     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
 *     <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
 *     <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
 *     <uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS"/>
 *     <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS"/>
 *     <p></p>
 *     READ_SETTINGS 用于判断是否存在快捷图标
 *     <p></p>
 *     @see <a href="https://www.jianshu.com/p/18be986553db"/>
 *     @see <a href="https://blog.csdn.net/m0_37218227/article/details/84071043"/>
 * </pre>
 */

object ShortCutExt {

    // ====================
    // = 检测是否存在快捷方式 =
    // ====================
    /**
     * 检测是否存在桌面快捷方式
     * @param name 快捷方式名称
     * @return `true` yes, `false` no
     */
    fun hasShortcut(name: String): Boolean {
        var cursor: Cursor? = null
        try {
            val context: Context = application
            val uri = Uri.parse("content://" + getAuthority(context) + "/favorites?notify=true")
            val resolver = context.contentResolver
            cursor = resolver.query(
                uri,
                arrayOf("title", "iconResource"),
                "title=?",
                arrayOf(name),
                null
            )
            // 判断是否存在快捷方式
            return cursor != null && cursor.count > 0
        } catch (e: Exception) {
            Timber.d( e, "hasShortcut")
        } finally {
            cursor?.close()
        }
        return false
    }


    // =================
    // = 创建桌面快捷方式 =
    // =================
    /**
     * 获取桌面快捷方式点击 Intent
     * @param clazz 快捷方式点击 Intent className(class.getName())
     * @return [Intent]
     */
    fun getShortCutIntent(clazz: Class<*>): Intent? {
        return  getShortCutIntent(clazz.name)
    }

    /**
     * 获取桌面快捷方式点击 Intent
     * @param className 快捷方式点击 Intent className(class.getName())
     * @return [Intent]
     */
    fun getShortCutIntent(className: String): Intent? {
            try {
                // 快捷方式点击 Intent 跳转
                val shortcutIntent = Intent(Intent.ACTION_MAIN)
                shortcutIntent.setClassName(application, className)
                shortcutIntent.flags =
                    Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                return shortcutIntent
            } catch (e: Exception) {
                Timber.d( e, "getShortCutIntent")
            }
        return null
    }
    
    // =
    /**
     * 创建桌面快捷方式
     * @param clazz 快捷方式点击 Intent class
     * @param name  快捷方式名称
     * @param icon  快捷方式图标
     * @return `true` success, `false` fail
     */
    fun addShortcut(
        clazz: Class<*>,
        name: String,
        icon: Int
    ): Boolean {
        return  addShortcut(clazz.name, name, icon)
    }

    /**
     * 创建桌面快捷方式
     * @param className 快捷方式点击 Intent className(class.getName())
     * @param name      快捷方式名称
     * @param icon      快捷方式图标
     * @return `true` success, `false` fail
     */
    fun addShortcut(
        className: String,
        name: String,
        icon: Int
    ): Boolean {
            try {
                // 快捷方式点击 Intent 跳转
                val shortcutIntent = Intent(Intent.ACTION_MAIN)
                shortcutIntent.setClassName(application, className)
                shortcutIntent.flags =
                    Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                return addShortcut(shortcutIntent, name, icon)
            } catch (e: Exception) {
                Timber.d( e, "addShortcut")
            }
        
        return false
    }

    /**
     * 创建桌面快捷方式
     * @param shortcutIntent 快捷方式点击 Intent 跳转
     * @param name           快捷方式名称
     * @param icon           快捷方式图标
     * @return `true` success, `false` fail
     */
    fun addShortcut(
        shortcutIntent: Intent,
        name: String,
        @AnyRes icon: Int
    ): Boolean {
        return addShortcut(shortcutIntent, name, icon, null)
    }

    /**
     * 创建桌面快捷方式
     * @param shortcutIntent 快捷方式点击 Intent 跳转
     * @param name           快捷方式名称
     * @param icon           快捷方式图标
     * @param pendingIntent  创建结果通知 (Android 8.0)
     * @return `true` success, `false` fail
     */
    fun addShortcut(
        shortcutIntent: Intent,
        name: String,
        icon: Int,
        pendingIntent: PendingIntent?
    ): Boolean {
            // Android 8.0 之前
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                try {
                    val context: Context = application
                    // 快捷方式图标
                    val iconRes = ShortcutIconResource.fromContext(context, icon)
                    // 创建快捷方式 Intent
                    val shortcut = Intent("com.android.launcher.action.INSTALL_SHORTCUT")
                    shortcut.putExtra("duplicate", false) // 不允许重复创建
                    shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name) // 快捷方式名称
                    shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent) // 快捷方式点击跳转
                    shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes)
                    // 发送广播, 创建快捷方式
                    context.sendBroadcast(shortcut)
                    return true
                } catch (e: Exception) {
                    Timber.d( e, "addShortcut")
                }
            } else { // Android 8.0 之后
                try {
                    val context: Context = application
                    // 获取 ShortcutManager
                    val shortcutManager: ShortcutManager = application.shortcutManager
                    // 如果默认桌面支持 requestPinShortcut(ShortcutInfo、IntentSender) 方法
                    if (shortcutManager.isRequestPinShortcutSupported) {
                        // 快捷方式创建相关信息
                        val shortcutInfo = ShortcutInfo.Builder(context, name.hashCode().toString())
                            .setIcon(Icon.createWithResource(context, icon)) // 快捷方式图标
                            .setShortLabel(name) // 快捷方式名字
                            .setIntent(shortcutIntent) // 快捷方式跳转 Intent
                            .build()
                        // 创建快捷方式
                        if (pendingIntent != null) {
                            shortcutManager.requestPinShortcut(
                                shortcutInfo,
                                pendingIntent.intentSender
                            )
                        } else {
                            shortcutManager.requestPinShortcut(shortcutInfo, null)
                        }
                        return true
                    }
                } catch (e: Exception) {
                    Timber.d( e, "addShortcut")
                }
            }
        return false
    }

    // =================
    // = 删除桌面快捷方式 =
    // =================
    /**
     * 删除桌面快捷方式
     * @param clazz 快捷方式点击 Intent class
     * @param name  快捷方式名称
     * @return `true` success, `false` fail
     */
    fun deleteShortcut(
        clazz: Class<*>,
        name: String
    ): Boolean {
        return  deleteShortcut(clazz.name, name)
    }

    /**
     * 删除桌面快捷方式
     * <pre>
     * Android 6.0 以后因存在安全隐患 Google 移除了 UninstallShortcutReceiver 无法进行删除桌面快捷
    </pre> *
     * @param className 快捷方式点击 Intent className(class.getName())
     * @param name      快捷方式名称
     * @return `true` success, `false` fail
     */
    fun deleteShortcut(
        className: String,
        name: String
    ): Boolean {
            try {
                val context: Context = application
                // 快捷方式 Intent
                val shortcutIntent = Intent(Intent.ACTION_MAIN)
                shortcutIntent.setClassName(context, className)
                // 删除快捷方式 Intent
                val shortcut = Intent("com.android.launcher.action.UNINSTALL_SHORTCUT")
                shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name) // 快捷方式名称
                shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent)
                context.sendBroadcast(shortcut)
                return true
            } catch (e: Exception) {
                Timber.d( e, "deleteShortcut")
            }
        return false
    }

    // ==========
    // = 内部方法 =
    // ==========
    /**
     * 获取 Authority
     * @param context [Context]
     * @return Authority
     */
    private fun getAuthority(context: Context): String {
        // 获取 Authority
        var authority = getAuthorityFromPermission(context)
        // 如果等于 null
        if (authority == null) {
            val version = Build.VERSION.SDK_INT
            authority = if (version < 8) { // Android 2.1.x (API 7) 以及以下的
                "com.android.launcher.settings"
            } else if (version < 19) { // Android 4.4 以下
                "com.android.launcher2.settings"
            } else { // 4.4 以及以上
                "com.android.launcher3.settings"
            }
            return authority
        }
        return authority
    }

    /**
     * 通过权限获取 Authority
     * @param context [Context]
     * @return Authority
     */
    private fun getAuthorityFromPermission(context: Context): String? {
        // 权限判断
        val permissions = arrayOf(
            "com.android.launcher.permission.WRITE_SETTINGS",
            "com.android.launcher.permission.READ_SETTINGS"
        )
        // 遍历权限
        for (permission in permissions) {
            try {
                val authority = getAuthorityFromPermission(context, permission)
                if (authority != null) {
                    return authority
                }
            } catch (e: Exception) {
                Timber.d( e, "getAuthorityFromPermission")
            }
        }
        return null
    }

    /**
     * 通过权限获取 Authority
     * <pre>
     * android 默认的 AUTHORITY 在 2.2 以后是 com.android.launcher2.settings
     * 但是不同的厂商可能会做不同的修改, 由于不同的厂商 uri 的前缀不同
     * 所以需要去查询 provider 获取真实的 content 的 uri 前缀
    </pre> *
     * @param context    [Context]
     * @param permission 权限
     * @return Authority
     */
    private fun getAuthorityFromPermission(
        context: Context,
        permission: String?
    ): String? {
        if (permission != null) {
            val lists = context.packageManager.getInstalledPackages(PackageManager.GET_PROVIDERS)
            if (lists != null) {
                for (packageInfo in lists) {
                    val providers = packageInfo.providers
                    if (providers != null) {
                        for (provider in providers) {
                            if (permission == provider.readPermission) {
                                return provider.authority
                            }
                            if (permission == provider.writePermission) {
                                return provider.authority
                            }
                        }
                    }
                }
            }
        }
        return null
    }
    
}

val Context.shortcutManager:ShortcutManager
    get() = getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager